using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

namespace SOEN341_SCHEDULER_PHASE1
{
    [Serializable()]
    class EducationalProgram : ISerializable
    {

        #region MEMBER_VARIABLES
        private string _name;
        private List<Course> _allCourses;
        private List<Student> _registeredStudents;
        #endregion

        #region SERIALIZATION
        /// <summary>
        /// Serialization constructor
        /// </summary>
        /// <param name="info"></param>
        /// <param name="ctxt"></param>
        public EducationalProgram(SerializationInfo info, StreamingContext ctxt)
        {
            //Get the values from info and assign them to the appropriate properties

            _name = (string)info.GetValue("name", typeof(string));
            _allCourses = (List<Course>)info.GetValue("allCourses", typeof(List<Course>));
            _registeredStudents = (List<Student>)info.GetValue("registeredStudents", typeof(List<Student>));
        }

        /// <summary>
        /// Serialization method
        /// </summary>
        /// <param name="info"></param>
        /// <param name="ctxt"></param>
        public void GetObjectData(SerializationInfo info, StreamingContext ctxt)
        {
            info.AddValue("name", _name);
            info.AddValue("allCourses", _allCourses);
            info.AddValue("registeredStudents", _registeredStudents);
        }
        #endregion

        #region CONSTRUCTORS

        /// <summary>
        /// default constructor
        /// </summary>
        public EducationalProgram()
        {
            _name = "UNDEFINED";
            _allCourses = new List<Course>();
            _registeredStudents = new List<Student>();
        }

        /// <summary>
        /// parameterizes constructor
        /// </summary>
        /// <param name="name">program name</param>
        /// <param name="allCourses">list of courses in program</param>
        public EducationalProgram(string name, List<Course> allCourses)
        {
            _name = name;
            //_allCourses = allCourses;

            _allCourses = new List<Course>();

            //gotta copy
            if (allCourses != null)
            {
                Course[] temp = allCourses.ToArray();
                for (int i = 0; i < temp.Length; i++)
                {
                    _allCourses.Add(temp[i]);
                }
            }
            _registeredStudents = new List<Student>();
        }
        #endregion

        #region ACCESSORS
        /// <summary>
        /// get courses in program
        /// </summary>
        /// <returns>list of courses in program</returns>
        public List<Course> GetAllCourses()
        {
            return _allCourses;
        }

        /// <summary>
        /// Get program name
        /// </summary>
        /// <returns>program name</returns>
        public string GetName()
        {
            return _name;
        }
        #endregion

        /// <summary>
        /// Adds a course to the program
        /// </summary>
        /// <param name="course">Course to add</param>
        /// <returns>TRUE: Courses added FALSE: course not added (courses already in program)</returns>
        public bool AddCourse(Course course)
        {
            if (!_allCourses.Contains(course))
            {
                _allCourses.Add(course);
                return true;
            }
            return false;
        }

        /// <summary>
        /// adds a student to the pgoram
        /// </summary>
        /// <param name="student">student to add</param>
        /// <returns>TRUE: student added FALSE: not added (already in program)</returns>
        public bool AddStudent(Student student)
        {
            if (!_registeredStudents.Contains(student))
            {
                _registeredStudents.Add(student);
                return true;
            }

            return false;
        }

        /// <summary>
        /// get registered student
        /// </summary>
        /// <returns>list of registered students</returns>
        public List<Student> GetRegisteredStudents()
        {
            return _registeredStudents;
        }

        /// <summary>
        /// Checks if courses is in program
        /// </summary>
        /// <param name="course">Course to verify</param>
        /// <returns>TRUE: course is in program FALSE: course is not in program</returns>
        public bool IsInProgramCore(Course course)
        {
            return (_allCourses.Contains(course));
        }

        /// <summary>
        /// To string
        /// </summary>
        /// <returns>returns program info</returns>
        public override string ToString()
        {
            return _name;
        }
    }
}
